﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.IO;
using System.Configuration;

namespace Kcadastro.classes
{
    public class importTXT
    {
        private string arquivo;
        private ARQUIVOPROP arqprop;
        private string _msg;
        public string MSG
        {
            get { return _msg; }
        }
        public bool _passou = true;
        public ARQUIVOPROP PROPRIEDADESARQUIVO
        {
            get { return arqprop; }
        }

        public importTXT()
        { 
        
        }

        public bool validarArquivo(string _arquivo, string _tipoArquivo)
        {
            bool ret = false;
            arqprop = new ARQUIVOPROP()
            {
                CAMINHO = _arquivo,
                NOMEARQUIVO = Path.GetFileName(_arquivo)
            };
            carregarArquivo(_arquivo, _tipoArquivo);

            ret = arqprop.HEADERVALIDO;

            return ret;
        }

        private void carregarArquivo(string _arquivo, string _tipoArquivo)
        {
            string _conteudo = "";
            Encoding enc = Encoding.GetEncoding("ISO-8859-1");
            FileInfo fi = new FileInfo(_arquivo);
            if (fi.Exists)
            {
                StreamReader sr = new System.IO.StreamReader(_arquivo, enc);
                _conteudo = sr.ReadToEnd();
                sr.Dispose();
                sr.Close();
                sr = null;
                var lineCount = File.ReadAllLines(_arquivo).Length;
                arqprop.QTDREGISTROS = lineCount;
                validaHeader(_arquivo, _tipoArquivo);
                validaCorpo(_arquivo, _tipoArquivo);
            }
            else
            {
                _conteudo = "";
            }
            fi = null;

        }

        private void validaHeader(string _arquivo, string _tipoArquivo)
        {
            string[] camposHeader = new string[1];
            string line = "";
            Encoding enc = Encoding.GetEncoding("ISO-8859-1");
            StreamReader sr = new System.IO.StreamReader(_arquivo, enc);
            
            string[] campos = new string[1];
            switch (_tipoArquivo)
            {
                case "3":
                    _msg = "";
                    line = "";
                    if (!sr.EndOfStream)
                    {
                        line = sr.ReadLine();
                    }
                    linhaOriginalPJ lopj = new linhaOriginalPJ();

                    if (!lopj.validaHeader(linha2campos( line, ";","")))
                    {
                        arqprop.HEADERVALIDO = false;
                        _msg = _msg + string.Format("\n Header Inválido; {0}",lopj.ERROS);
                    }
                    else
                    { 
                        arqprop.HEADERVALIDO = true;
                    }
                    break;
                case "4":
                    _msg = "";
                    line = "";
                    if (!sr.EndOfStream)
                    {
                        line = sr.ReadLine();
                    }
                    linhaOriginalPF lopf = new linhaOriginalPF();

                    if (!lopf.validaHeader(line))
                    {
                        arqprop.HEADERVALIDO = false;
                        _msg = _msg + string.Format("\n Header Inválido; {0}",lopf.ERROS);
                    }
                    else
                    { 
                        arqprop.HEADERVALIDO = true;
                    }
                    

                    break;
            }
            sr.Dispose();
            sr.Close();
            sr = null;
        }

        private void validaCorpo(string _arquivo, string _tipoArquivo)
        {
            //string[] camposHeader = new string[1];
            string line = "";
            int count = 0;
            int countErros = 0;
            Encoding enc = Encoding.GetEncoding("ISO-8859-1");
            StreamReader sr = new System.IO.StreamReader(_arquivo, enc);
            string[] campos = new string[1];
            switch (_tipoArquivo)
            {
                case "3":
                    //_msg = "";
                    line = "";
                    arqprop.CORPOVALIDO = true;
                    while (!sr.EndOfStream)
                    {
                        linhaOriginalPJ lopj = new linhaOriginalPJ();
                        line = sr.ReadLine();
                        if (count != 0)
                        {
                            if (lopj.autoCarga(linha2campos(line, ";", "\"")))
                            {
                                if (!lopj.validaLinha())
                                {
                                    countErros++;
                                    _msg = _msg + string.Format("\n Linha {0} inválida; {1}", count + 1, lopj.ERROS);
                                    //arqprop.CORPOVALIDO = false;
                                }
                            }
                            else
                            {
                                _msg = _msg + string.Format("\n Linha {0} inválida; {1}", count + 1, lopj.ERROS);
                                //arqprop.CORPOVALIDO = false;
                            }
                        }
                        count++;
                    }

                    PorcentagemErros(countErros,count,ref arqprop);

                    break;
                case "4":
                   //_msg = "";
                    line = "";
                    arqprop.CORPOVALIDO = true;
                    while (!sr.EndOfStream)
                    {
                        linhaOriginalPF lopf = new linhaOriginalPF();
                        line = sr.ReadLine();
                        if (count != 0)
                        {
                            if (lopf.autoCarga(linha2campos(line, ";", "\"")))
                            {
                                if (!lopf.validaLinha())
                                {
                                    countErros++;
                                    _msg = _msg + string.Format("\n Linha {0} inválida; {1}", count + 1, lopf.ERROS);
                                    //arqprop.CORPOVALIDO = false;
                                }
                            }
                            else
                            {
                                _msg = _msg + string.Format("\n Linha {0} inválida; {1}", count + 1, lopf.ERROS);
                                //arqprop.CORPOVALIDO = false;
                            }
                            
                        }
                        count++;
                    }

                    PorcentagemErros(countErros, count, ref arqprop);
                    
                    break;
            }
            
            sr.Dispose();
            sr.Close();
            sr = null;
        }

        public List<string> linha2campos(string _linha, string _separador, string _quota)
        {
            List<string> ret = new List<string>();
            string campo = "";
            bool inquota = false;
            // tira enter do final
            _linha = _linha.Replace("\n", "").Replace("\r", "") + ";" ;
            // defini qtd de caracteres da linha
            int i = _linha.Length;
                for (int x = 0; x < i; x++)
                {
                    if (_linha.Substring(x, 1) != _quota )
                    {
                        if (_linha.Substring(x, 1) != _separador)
                        {
                            campo = campo + _linha.Substring(x, 1);
                        }
                        else if (_linha.Substring(x,1) == _separador && inquota)
                        {
                            campo = campo + _linha.Substring(x, 1);
                        }
                    }
                    else
                    { 
                        inquota = inquota ? false: true;

                    }
                    if (_linha.Substring(x, 1) == _separador && !inquota)
                    {

                        //inquota = false;
                        ret.Add(campo);
                        campo = "";
                    }


                    //if (_linha.Substring(x, 1) == _quota)
                    //{
                    //    if (inquota)
                    //    {
                    //        inquota = false;
                    //        //ret.Add(campo);
                    //        //campo = "";
                    //    }
                    //    else
                    //    {
                    //        inquota = true;
                    //    }
                    //}
                    //else 
                    //{ }

                    //if (!inquota && _linha.Substring(x, 1) == _separador)
                    //{
                    //    inquota = false;
                    //    ret.Add(campo);
                    //    campo = "";
                    //}


                    //if (inquota && _linha.Substring(x, 1) != _quota)
                    //{
                    //    campo = campo + _linha.Substring(x, 1);   
                    //}
                        
                    
                }
            if (campo.Trim() != "")
                ret.Add(campo);
            
            return ret;
        }


        private List<string> linha2List(string _linha)
        {
            List<string> ls = new List<string>();
            string campo = "";
            bool a1 = false; // primeira aspas
            bool a2 = false; // segunda aspas
            for (int x = 0; x < _linha.Length - 1; x++)
            {
                if (_linha.Substring(x, 1) == "\"")
                {
                    if (a1 && !a2)
                    {
                        a1 = false;
                        a2 = true;
                    }
                    else if (!a1 && a2)
                    {
                        a1 = true;
                        a2 = false;
                    }
                    else
                    {
                        a1 = true;
                        a2 = false;
                    }
                }

                if (a1 && !a2 && _linha.Substring(x, 1) != "\"")
                {
                    campo = campo + _linha.Substring(x, 1);
                }

                if (!a1 && a2 && _linha.Substring(x, 1) == "\"")
                {
                    ls.Add(campo);
                    campo = "";
                }

            }


            return ls;
        }

        //TODO: BEGIN SJC - verifica a porcentagem de erros
        //Data: 28/06/2012
        private void PorcentagemErros(long qtdErros, long qtdLinhas,ref ARQUIVOPROP _arquProp)
        {
            String strPorcetagemAceite = ConfigurationManager.AppSettings["vrPorcetagemAceite"];
            int PorcetagemAceite = Convert.ToInt32(strPorcetagemAceite);

            double linhas = qtdLinhas * PorcetagemAceite / 100;
            
            if (qtdErros > linhas)
            {
                _arquProp.CORPOVALIDO = false;
            }
        }
        //TODO: END
    }

    public class linhaOriginalPJ
    { 
        public string CODIGO {get;set;}
        public string EMPRESA { get; set; }
        public string FILIAL { get; set; }
        public string CNPJ { get; set; }
        public string RAZAO { get; set; }
        public string FANTASIA { get; set; }
        public string LOGRADOURO { get; set; }
        public string NUM { get; set; }
        public string COMPLEMENTO { get; set; }
        public string BAIRRO { get; set; }
        public string MUNICIPIO { get; set; }
        public string UF { get; set; }
        public string CEP { get; set; }
        public string IE { get; set; }
        public string IBGE { get; set; }
        public string CCM { get; set; }
        public string CNAE { get; set; }
        public string SUFRAMA { get; set; }

        public string ERROS { get; set; }

        public string[] camposHeader 
        {
            get{
                return new string[]{
                        "CODIGO", "EMPRESA", "FILIAL", "CNPJ", "RAZAO", "FANTASIA", "LOGRADOURO", "NUM", "COMPLEMENTO", "BAIRRO", "MUNICIPIO", "UF", "CEP", "IE", "IBGE", "CCM", "CNAE", "SUFRAMA" };
                }
        }

        public bool validaHeader(string _linha0)
        {
            bool ret = true;
            string[] campos = _linha0.Split(';');
            if (campos.Length >= 18)
            {
                ret = true;

                for (int i = 0; i < 18; i++)
                {
                    if (campos[i].ToUpper() != camposHeader[i])
                    {
                        ret = false;
                        ERROS = ERROS + string.Format("\n O campo {0} não está na posição {1} do CSV.", camposHeader[i].ToString(), (i + 1).ToString());
                    }
                }
            }
            else
            {
                ret = false;
            }
            return ret;
        }

        public bool validaHeader(List<string> ls)
        {
            bool ret = true;
            //string[] campos = _linha0.Split(';');
            if (ls.Count() >= 18)
            {
                ret = true;
                for (int i = 0; i < 18; i++)
                {
                    if (ls[i].ToString() != camposHeader[i])
                    {
                        ret = false;
                        ERROS = ERROS + string.Format("\n O campo {0} não está na posição {1} do CSV.", camposHeader[i].ToString(), (i + 1).ToString());

                    }
                }
            }
            else
            {
                ret = false;
            }
            //if (campos.Length >= 18)
            //{
            //    ret = true;

            //    for (int i = 0; i < 18; i++)
            //    {
            //        if (campos[i].ToUpper() != camposHeader[i])
            //        {
            //            ret = false;
            //            ERROS = ERROS + string.Format("\n O campo {0} não está na posição {1} do CSV.", camposHeader[i].ToString(), (i + 1).ToString());
            //        }
            //    }
            //}
            //else
            //{
            //    ret = false;
            //}
            return ret;
        }

        public string LINHA
        {
            get{
                string ret = "";
                
                ret = ret + "\"" + CODIGO + "\";";
                ret = ret + "\"" + EMPRESA  + "\";";
                ret = ret + "\"" +  FILIAL  + "\";";
                ret = ret + "\"" +  CNPJ  + "\";";
                ret = ret + "\"" +  RAZAO  + "\";";
                ret = ret + "\"" +  FANTASIA  + "\";";
                ret = ret + "\"" +  LOGRADOURO  + "\";";
                ret = ret + "\"" +  NUM  + "\";";
                ret = ret + "\"" +  COMPLEMENTO  + "\";";
                ret = ret + "\"" +  BAIRRO  + "\";";
                ret = ret + "\"" +  MUNICIPIO  + "\";";
                ret = ret + "\"" +  UF  + "\";";
                ret = ret + "\"" +  CEP  + "\";";
                ret = ret + "\"" +  IE  + "\";";
                ret = ret + "\"" + IBGE + "\";";
                ret = ret + "\"" + CCM + "\";";
                ret = ret + "\"" + CNAE + "\";";
                ret = ret + "\"" +  SUFRAMA  + "\";";

                return ret;
            }
        }
           
        public bool autoCarga (List<string> campos)        
        {
            bool ret = true;
            if (campos.Count >= 18)
            {
                CODIGO = campos[0];
                EMPRESA = campos[1];
                FILIAL = campos[2];
                CNPJ = campos[3];
                RAZAO = campos[4];
                FANTASIA = campos[5];
                LOGRADOURO = campos[6];
                NUM = campos[7];
                COMPLEMENTO = campos[8];
                BAIRRO = campos[9];
                MUNICIPIO = campos[10];
                UF = campos[11];
                CEP = campos[12];
                IE = campos[13];
                IBGE = campos[14];
                CCM = campos[15];
                CNAE = campos[16];
                SUFRAMA = campos[17];
                ret = true;
            }
            else
            { 
                ret = false;
                ERROS = ERROS + "linha não contem todos os campos.";
            }
            return ret;
        }

        public bool validaLinha()
        {
            bool ret = true;
            string __tcnpj = CNPJ.Replace(".", "").Replace("/", "").Replace("-", "");
            if (!FW.validador.ValidaCnpj(CNPJ))
            {
                ret = false;
                ERROS = ERROS + "CNPJ MAL FORMATADO";
            }
            if (RAZAO.Trim() == "")
            {
                ret = false;
                ERROS = ERROS + " | RAZAO SOCIAL vazia";
            }

            return ret;
        }
    }

    public class linhaOriginalPF
    {
        public string CODIGO { get; set; }
        public string EMPRESA { get; set; }
        public string FILIAL { get; set; }
        public string CPF { get; set; }
        public string NOME { get; set; }
        public string LOGRADOURO { get; set; }
        public string NUM { get; set; }
        public string COMPLEMENTO { get; set; }
        public string BAIRRO { get; set; }
        public string MUNICIPIO { get; set; }
        public string UF { get; set; }
        public string CEP { get; set; }
        public string IBGE { get; set; }
        
        public string ERROS { get; set; }

        public string[] camposHeader
        {
            get
            {
                return new string[]{
                       "CODIGO", "EMPRESA", "FILIAL", "CPF", "NOME", "LOGRADOURO", "NUM", "COMPLEMENTO", "BAIRRO", "MUNICIPIO", "UF", "CEP","IBGE"
                    };
            }
        }

        public bool validaHeader(string _linha0)
        {
            bool ret = true;
            string[] campos = _linha0.Split(';');
            if (campos.Length >= 13)
            {
                ret = true;

                for (int i = 0; i < 13; i++)
                {
                    if (campos[i].ToUpper() != camposHeader[i])
                    {
                        ret = false;
                        ERROS = ERROS + string.Format("\n O campo {0} não está na posição {1} do CSV.", camposHeader[i].ToString(), (i + 1).ToString());
                    }
                }
            }
            else
            {
                ret = false;
            }
            return ret;
        }

        public string LINHA
        {
            get
            {
                string ret = "";

                ret = ret + "\"" + CODIGO + "\";";
                ret = ret + "\"" + EMPRESA + "\";";
                ret = ret + "\"" + FILIAL + "\";";
                ret = ret + "\"" + CPF + "\";";
                ret = ret + "\"" + NOME + "\";";
                ret = ret + "\"" + LOGRADOURO + "\";";
                ret = ret + "\"" + NUM + "\";";
                ret = ret + "\"" + COMPLEMENTO + "\";";
                ret = ret + "\"" + BAIRRO + "\";";
                ret = ret + "\"" + MUNICIPIO + "\";";
                ret = ret + "\"" + UF + "\";";
                ret = ret + "\"" + CEP + "\";";
                ret = ret + "\"" + IBGE + "\";";
                
                return ret;
            }
        }

        public bool autoCarga(List<string> campos)
        {
            bool ret = true;
            if (campos.Count >= 13)
            {
                CODIGO = campos[0];             
                EMPRESA = campos[1];
                FILIAL = campos[2];
                CPF = campos[3];
                NOME = campos[4];
                LOGRADOURO = campos[5];
                NUM = campos[6];
                COMPLEMENTO = campos[7];
                BAIRRO = campos[8];
                MUNICIPIO = campos[9];
                UF = campos[10];
                CEP = campos[11];
                IBGE = campos[12];
                ret = true;
            }
            else
            {
                ret = false;
                ERROS = ERROS + "linha não contem todos os campos.";
            }
            return ret;
        }

        public bool validaLinha()
        {
            bool ret = true;
            try
            {
                string _cpf = string.Format("{0:00000000000}",Convert.ToInt64(CPF));
                if (!FW.validador.ValidaCPF( _cpf))
                {
                    ret = false;
                    ERROS = ERROS + "CPF MAL FORMATADO";
                }
            }
            catch (Exception ex)
            {
                ret = false;
                ERROS = ERROS + "CPF MAL FORMATADO";
            }
            if (NOME.Trim() == "")
            {
                ret = false;
                ERROS = ERROS + " | Campo NOME vazio";
            }

            return ret;
        }
    }


    public class ARQUIVOPROP
    {
        public string CAMINHO { get; set; }
        public string CONTEUDO { get; set; }
        public string NOMEARQUIVO { get; set; }
        public int QTDREGISTROS { get; set; }
        public bool HEADERVALIDO { get; set; }
        public bool CORPOVALIDO { get; set; }
        public bool VALIDO { get; set; }
        public int IDUSER { get; set; }
    }
}